﻿using System.Collections.Generic;

using Microsoft.Xna.Framework.Graphics;

using Utilities;
using Microsoft.Xna.Framework;

namespace SceneManager.Processors
{
    public enum RenderType
    {
        ToScreen,
        ToTexture
    }

    public class RenderGraph : Graph<Processor>
    {
        public virtual void Process(Camera camera, GameTime gameTime)
        {
            Process(camera, gameTime, RenderType.ToScreen);
        }
        public virtual Texture2D Process(Camera camera, GameTime gameTime, RenderType renderType)
        {
            Texture2D output = null;

            foreach (GraphElement<Processor> element in Elements)
            {
                if (element.Value is TextureProcessor)
                {
                    List<Pair<GraphPin<Processor>, GraphPin<Processor>>> inputs = new List<Pair<GraphPin<Processor>,GraphPin<Processor>>>();
                    foreach (GraphPin<Processor> pin in element.InputPins)
                        foreach (GraphPin<Processor> link in pin.IncomingLinks)
                            inputs.Add(new Pair<GraphPin<Processor>,GraphPin<Processor>>(link, pin));

                    TextureProcessor processor = element.Value as TextureProcessor;
                    foreach (var input in inputs)
                        processor.Inputs[input.Value2.Name] = input.Value1.Element.Value.Outputs[input.Value1.Name];
                }

                if (element.Value is IFinalRenderer)
                    output = (element.Value as IFinalRenderer).Render(camera, gameTime, renderType);
                else
                    element.Value.Process(camera, gameTime);
            }

            return output;
        }

        public new void Add(string name, Processor value)
        {
            GraphElement<Processor> element = new GraphElement<Processor>(name, value);
            
            foreach(string output in value.Outputs.Keys)
                element.AddOutputPin(output);
            if (value is TextureProcessor)
                foreach(string input in (value as TextureProcessor).Inputs.Keys)
                    element.AddInputPin(input);

            Add(element);
        }
        public void Link(string outputElementName, string inputElementName)
        {
            Link(outputElementName, "Output", inputElementName, "Input");
        }
    }
}
